package com.ossfk.net.server.adapter;

import com.ossfk.net.config.NetServerConfig;
import com.ossfk.net.session.TcpSession;
import com.ossfk.net.session.TcpSessionManager;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class AbstractServerAdapter extends ChannelInboundHandlerAdapter {
	private TcpSessionManager TcpSessionManager;
	private NetServerConfig config;

	public AbstractServerAdapter() {
	}

	public AbstractServerAdapter(NetServerConfig config) {
		this.config = config;
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// 建立连接时
		log.info("New Connection,remoteAddress:{}", ctx.channel().remoteAddress());
		// 保存session
		if (TcpSessionManager != null) {
			TcpSessionManager.addSession(TcpSession.buildSession(ctx.channel()));
		}
		super.channelActive(ctx);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		log.info("Connection is closed,remoteAddress:{}", ctx.channel().remoteAddress());
		if (TcpSessionManager != null) {
			TcpSessionManager.removeBySessionId(TcpSession.buildId(ctx.channel()));
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("发生异常:{}", cause.getMessage());
//		log.debug("发生异常", cause);
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		try {
			TcpSession session = null;
			if (TcpSessionManager != null) {
				String sessionId = TcpSession.buildId(ctx.channel());
				session = TcpSessionManager.updateLastCommunicateTime(sessionId);
			}
			handleMessage(session, msg);
		} catch (Exception e) {
			log.error("读包时发生异常:{}", e.getMessage());
//			log.debug("读包时发生异常", e);
		} finally {
			// 释放已经读完的字节
			ReferenceCountUtil.release(msg);
		}
	}

	/**
	 * 消息处理
	 * 
	 * @param session 会话
	 * @param msg
	 * @author Liujiefu
	 * @date 2020-03-18 11:08:50
	 */
	public abstract void handleMessage(TcpSession session, Object msg);

	public TcpSessionManager getTcpSessionManager() {
		return TcpSessionManager;
	}

	public void setTcpSessionManager(TcpSessionManager tcpSessionManager) {
		TcpSessionManager = tcpSessionManager;
	}

	public NetServerConfig getConfig() {
		return config;
	}

	public void setConfig(NetServerConfig config) {
		this.config = config;
	}
}
